/*
 * ViewInvoiceHandler.java
 * 
 * @version 1.0, April 29, 2011
 * CS 2340 Team 10: Cyberdyne Systems
 */
package edu.gatech.oad.cyberdoc.domain.action;

import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import edu.gatech.oad.cyberdoc.domain.Admin;
import edu.gatech.oad.cyberdoc.domain.Doctor;
import edu.gatech.oad.cyberdoc.domain.Invoice;
import edu.gatech.oad.cyberdoc.domain.Patient;
import edu.gatech.oad.cyberdoc.domain.Staff;
import edu.gatech.oad.cyberdoc.domain.User;

/**
 * Handles user actions related to viewing invoices.
 * 
 * @author John Girata
 * @version 1.0, April 29, 2011
 */
public class ViewInvoiceHandler extends ActionHandler {

	/**
	 * The action code this ActionHandler corresponds to.
	 */
	public static final String[] ACTION_CODES;

	/**
	 * The logger for this class.
	 */
	private static final Logger LOG;

	static {
		ACTION_CODES = new String[] { "view_invoice", "view_invoices" };
		LOG = Logger.getLogger("edu.gatech.oad.cyberdoc.action."
				+ "ViewUsersHandler");
	}

	/**
	 * Registers this handler with the classes through which it can respond to
	 * request.
	 */
	public ViewInvoiceHandler() {
		for (String code : ACTION_CODES) {
			Patient.addActionHandler(code, this);
			Staff.addActionHandler(code, this);
			Doctor.addActionHandler(code, this);
			Admin.addActionHandler(code, this);
		}
	}

	/**
	 * Reverses the registrations performed by the constructor.
	 */
	@Override
	public void destroy() {
		Patient.removeActionHandler(this);
		Staff.removeActionHandler(this);
		Doctor.removeActionHandler(this);
		Admin.removeActionHandler(this);
	}

	/**
	 * Handles user actions related to viewing invoices.
	 * 
	 * This method expects the following fields:
	 * 
	 * id (optional): If specified, the single invoice will be returned; if not,
	 * a list of all available invoices will be returned
	 * 
	 * This method will return the following fields:
	 * 
	 * invoices: if id is not specified, a JSONArray of JSONObjects containing
	 * all invoices (without their line items)
	 * 
	 * invoice: if id is specified, the JSONObject representation of the invoice
	 * 
	 * @param source
	 *            The user that called this method
	 * @param command
	 *            The command encoding the action
	 * @return The result of performing this action
	 * @throws ActionHandleException
	 *             If a required field does not exist in the command, or if the
	 *             usernames given for the patient and doctor are invalid
	 */
	@Override
	public JSONObject handle(User source, JSONObject command)
			throws ActionHandleException {
		LOG.info("Handling view_invoice action");

		if (source == null) {
			final String message = "Source user cannot be null";
			LOG.severe(message);
			throw new ActionHandleException(new NullPointerException(message));
		}

		final JSONObject response = new JSONObject();

		try {
			if (command.has("id")) {
				final int id = command.getInt("id");
				final Invoice invoice = Invoice.getInvoice(id);
				
				response.put("invoice", invoice.toJSONObject());
				response.put("next", "view_invoice");
			} else {
				final List<Invoice> invoices = Invoice.getAllInvoices();
				final JSONArray array = new JSONArray();

				for (Invoice invoice : invoices) {
					final JSONObject object = invoice.toJSONObject();
					object.remove("items");
					array.put(object);
				}

				response.put("invoices", array);
				response.put("next", "view_invoices");
			}
		} catch (JSONException e) {
			LOG.log(Level.SEVERE, "Unexpected JSONException.", e);
			throw new ActionHandleException(e);
		}

		return response;
	}

	/**
	 * Returns a string representation of this object.
	 * 
	 * @return A string representation of this object
	 * @see java.lang.Object#toString()
	 */
	@Override
	public String toString() {
		return "ViewInvoiceHandler";
	}
}
